package org.fastsyncer.worker.framework;

import java.util.concurrent.ConcurrentLinkedQueue;

import org.fastsyncer.common.entity.MappingTask;
import org.fastsyncer.parser.framework.ParserFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WorkerFactory {

	private static Logger logger = LoggerFactory.getLogger(WorkerFactory.class);

	private static WorkerFactory instance = new WorkerFactory();

	private WorkerFactory() {
	}

	public static WorkerFactory getInstance() {
		return instance;
	}

	/**
	 * 全量同步
	 * 
	 * @param mappingTask
	 * @param distributeTask
	 * @return
	 * @throws JSONException 
	 * @throws InterruptedException 
	 */
	public JSONObject handle(MappingTask mappingTask, ConcurrentLinkedQueue<Integer[]> distributeTask) throws InterruptedException, JSONException {
		logger.info("Task:" + mappingTask.getId());
		// 执行批量同步任务
		return new WorkerThreadPool().sync(mappingTask, distributeTask);
	}

	/**
	 * 增量同步
	 * 
	 * @param mappingTask
	 * @param msg
	 * @return
	 * @throws JSONException
	 */
	public JSONObject handle(MappingTask mappingTask, JSONObject msg) throws JSONException {
		// 同步结果
		JSONObject result = new JSONObject();
		result.put("reason", new JSONArray());
		int fail = 0;
		
		JSONArray arr = msg.getJSONArray("msg");
		int msgLen = arr.length();
		for (int i = 0; i < msgLen; i++) {
			JSONObject row = (JSONObject) arr.get(i);
			try {
				// 执行增量操作，如果失败会抛出异常，否则返回true
				ParserFactory.getInstance().parse(mappingTask, row);
			} catch (Exception e) {
				fail++;
				handleException(e, result, mappingTask, row.getJSONArray("before"), row.getJSONArray("after"));
			}
		}
		result.put("fail", fail);
		return result;
	}

	private void handleException(Exception e, JSONObject result, MappingTask mappingTask, JSONArray before,
			JSONArray after) {
		try {
			// 记录错误信息
			JSONObject err = new JSONObject();
			err.put("params", (after == null || after.length() < 1 ? before : after));
			err.put("cause", e.getCause());
			err.put("message", e.getMessage());
			result.getJSONArray("reason").put(err);
		} catch (JSONException e1) {
			logger.error("记录错误信息时：转换JSONObject异常！");
		}
	}

}
